package jch.learn.java.advanced.chapter1_stream.streams;

import java.io.IOException;
import java.math.BigInteger;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

// 流的创建

// java.util.stream.Stream
// static <T> Stream<T> of(T... values) 产生一个元素给定值的流
// static <T> Stream<T> empty() 产生一个无元素的流
// static <T> Stream<T> generate(Supplier<T> s) 产生一个无限流，元素通过调用函数s构建
// static <T> Stream<T> iterate(T seed,UnaryOperator<T> f) 产生一个无限流，元素包含种子，在种子上调用f产生的值、在前一个元素上调用f产生的值

// java.util.Arrays
// static <T> Stream<T> stream(T[] array,int startInclusive,int endExclusive) 产生一个流，元素为数组指定范围内的元素构成

// java.util.regex.Pattern
// Stream<String> splitAsStream(CharSequence input) 产生一个流，元素为输入中该模式界定的部分

// java.nio.file.Files
// static Stream<String> lines(Path path)
// static Stream<String> lines(Path path,Charset cs) 产生一个流，元素为指定文件中的行，默认文件字符集为UTF-8，或指定字符集

// java.util.function.Supplier<T>
// T get() 提供一个值
public class CreatingStreams {

    public static <T> void show(String title, Stream<T> stream){
        final int SIZE = 10;
        List<T> firstElements = stream.limit(SIZE + 1).collect(Collectors.toList());
        System.out.print(title + ": ");
        for (int i = 0; i < firstElements.size(); i++) {
            if (i > 0) System.out.print(", ");
            if (i < SIZE) System.out.print(firstElements.get(i));
            else System.out.print("...");
        }
        System.out.println();
    }

    public static void main(String[] args) throws URISyntaxException, IOException {
        Path path = Paths.get(CreatingStreams.class.getResource("/gutenberg/alice30.txt").toURI());
        String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);

        Stream<String> words = Stream.of(contents.split("\\PL+"));
        show("words",words);

        Stream<String> song = Stream.of("gently","down","the","stream");
        show("song",song);

        Stream<String> silence = Stream.empty();
        show("silence",silence);

        // -------------------------------------

        Stream<String> echos = Stream.generate(() -> "Echo");
        show("echos",echos);

        Stream<Double> randoms = Stream.generate(Math::random);
        show("randoms",randoms);

        // --------------------------------------

        Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE));
        show("integers",integers);

        // ----------------------------------------
        Stream<String> wordsAnotherWay = Pattern.compile("\\PL+").splitAsStream(contents);
        show("wordsAnotherWay",wordsAnotherWay);

        Stream<String> lines = Files.lines(path,StandardCharsets.UTF_8);
        show("lines",lines);
    }
}
